﻿//// ReSharper disable all Spelling

using Microsoft.Win32.SafeHandles;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace Instrument.Ports
{
    public partial class WindowsApiSerialPort
    {
        #region Windows API 常量定义

        private const int ERROR_IO_PENDING = 997;

        private const uint GENERIC_READ = 0x80000000;
        private const uint GENERIC_WRITE = 0x40000000;
        private const uint OPEN_EXISTING = 3;
        private const uint FILE_ATTRIBUTE_NORMAL = 0x80;
        private const uint FILE_FLAG_OVERLAPPED = 0x40000000;

        // 波特率常量
        private const uint CBR_110 = 110;

        private const uint CBR_300 = 300;
        private const uint CBR_600 = 600;
        private const uint CBR_1200 = 1200;
        private const uint CBR_2400 = 2400;
        private const uint CBR_4800 = 4800;
        private const uint CBR_9600 = 9600;
        private const uint CBR_14400 = 14400;
        private const uint CBR_19200 = 19200;
        private const uint CBR_38400 = 38400;
        private const uint CBR_56000 = 56000;
        private const uint CBR_57600 = 57600;
        private const uint CBR_115200 = 115200;
        private const uint CBR_128000 = 128000;
        private const uint CBR_256000 = 256000;

        // 校验位常量
        private const byte NOPARITY = 0;

        private const byte ODDPARITY = 1;
        private const byte EVENPARITY = 2;
        private const byte MARKPARITY = 3;
        private const byte SPACEPARITY = 4;

        // 停止位常量
        private const byte ONESTOPBIT = 0;

        private const byte ONE5STOPBITS = 1;
        private const byte TWOSTOPBITS = 2;

        // 流控制常量
        private const uint DTR_CONTROL_DISABLE = 0x00;

        private const uint DTR_CONTROL_ENABLE = 0x01;
        private const uint DTR_CONTROL_HANDSHAKE = 0x02;
        private const uint RTS_CONTROL_DISABLE = 0x00;
        private const uint RTS_CONTROL_ENABLE = 0x01;
        private const uint RTS_CONTROL_HANDSHAKE = 0x02;
        private const uint RTS_CONTROL_TOGGLE = 0x03;

        // 文件打开模式
        private const uint FILE_SHARE_NONE = 0x00000000;        // 独占访问

        private const uint FILE_SHARE_READ = 0x00000001;       // 允许其他程序读取
        private const uint FILE_SHARE_WRITE = 0x00000002;       // 允许其他程序写入
        private const uint FILE_SHARE_DELETE = 0x00000004;      // 允许其他程序删除

        #endregion Windows API 常量定义

        #region Windows API 结构体定义

        [StructLayout(LayoutKind.Sequential)]
        public struct DCB
        {
            public int DCBlength;
            public uint BaudRate;
            public uint Flags;
            public ushort wReserved;
            public ushort XonLim;
            public ushort XoffLim;
            public byte ByteSize;
            public byte Parity;
            public byte StopBits;
            public byte XonChar;
            public byte XoffChar;
            public byte ErrorChar;
            public byte EofChar;
            public byte EvtChar;
            public ushort wReserved1;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct COMMTIMEOUTS
        {
            public uint ReadIntervalTimeout;
            public uint ReadTotalTimeoutMultiplier;
            public uint ReadTotalTimeoutConstant;
            public uint WriteTotalTimeoutMultiplier;
            public uint WriteTotalTimeoutConstant;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct OVERLAPPED
        {
            public UIntPtr Internal;
            public UIntPtr InternalHigh;
            public uint Offset;
            public uint OffsetHigh;
            public IntPtr hEvent;
        }

        #endregion Windows API 结构体定义

        #region Windows API 函数声明

        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern SafeFileHandle CreateFile(
            string lpFileName,
            uint dwDesiredAccess,
            uint dwShareMode,
            IntPtr lpSecurityAttributes,
            uint dwCreationDisposition,
            uint dwFlagsAndAttributes,
            IntPtr hTemplateFile);

        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern bool GetCommState(
            SafeFileHandle hFile,
            ref DCB lpDCB);

        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern bool SetCommState(
            SafeFileHandle hFile,
            ref DCB lpDCB);

        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern bool GetCommTimeouts(
            SafeFileHandle hFile,
            ref COMMTIMEOUTS lpCommTimeouts);

        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern bool SetCommTimeouts(
            SafeFileHandle hFile,
            ref COMMTIMEOUTS lpCommTimeouts);

        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern bool ReadFile(
            SafeFileHandle hFile,
            byte[] lpBuffer,
            uint nNumberOfBytesToRead,
            out uint lpNumberOfBytesRead,
            ref OVERLAPPED lpOverlapped);

        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern bool WriteFile(
            SafeFileHandle hFile,
            byte[] lpBuffer,
            uint nNumberOfBytesToWrite,
            out uint lpNumberOfBytesWritten,
            ref OVERLAPPED lpOverlapped);

        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern bool PurgeComm(
            SafeFileHandle hFile,
            uint dwFlags);

        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern bool SetupComm(
            SafeFileHandle hFile,
            uint dwInQueue,
            uint dwOutQueue);

        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern bool GetOverlappedResult(
            SafeFileHandle hFile,
            ref OVERLAPPED lpOverlapped,
            out uint lpNumberOfBytesTransferred,
            bool bWait);

        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern IntPtr CreateEvent(IntPtr lpEventAttributes, bool bManualReset, bool bInitialState, string lpName);

        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern bool CloseHandle(IntPtr hObject);

        #endregion Windows API 函数声明
    }
}